﻿using OT.HikiSecureCenterApis.Req;
using OT.HikiSecureCenterApis.Res;
using OT.HikiSecureCenterApis.Service.OneCard.Req;
using OT.HikiSecureCenterApis.Service.OneCard.Res;

namespace OT.HikiSecureCenterApis.Service.OneCard
{
    /// <summary>
    /// 一卡通应用服务 --> 门禁管理
    /// </summary>
    public partial class OneCardService : ServiceBase
    {
        public OneCardService(HikiSecureCenterApis _SecureCenterApis) : base(_SecureCenterApis) { }

        #region 门禁功能接口
        /// <summary>
        /// 查询门禁点状态 /api/acs/v1/door/states
        /// 该接口支持门常开、门常闭、门开和门闭四种操作引起的门状态获取。门常开操作，门会一直处于开状态，不会自动关闭，执行门闭操作，门才会关上；
        /// 门常闭操作，门会一直处于关毕状态，普通卡刷卡门不会被打开，执行门开操作，门会打开；
        /// 门开操作，执行门打开动作，超过门打开时间，门会自动关上；门闭操作，执行关门动作，会立即把门关上。
        /// 调用该接口，首先要通过获取门禁点资源列表的接口，获取到门禁点唯一编号，然后根据门禁点唯一编号进行门禁点状态状态查询。
        /// 需要注意的是门通道必须接上门磁才能正常发送门状态变化通知，如果未接门磁，平台无法通过门状态变更通知来更新门状态。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.3及以上版本</remarks>
        /// <param name="doorIndexCodes">非必填 门禁点唯一标识，最大支持200个门禁点。查询门禁点列表v2接口获取返回参数doorIndexCode
        /// https://open.hikvision.com/docs/794bb3aa9864418780fae0efb9d8745b?curNodeId=794bb3aa9864418780fae0efb9d8745b#b40ec5e7
        /// </param>
        /// <returns><see cref="ResDoorStates"/></returns>
        public async Task<ResParameter<ResDoorStates>?> DoorStatesAsync(IList<string> doorIndexCodes) =>
          await SecureCenterApis.PostAsync<ResDoorStates>("/api/acs/v1/door/states", 1.3, new { doorIndexCodes = doorIndexCodes });
        /// <summary>
        /// 门禁点反控 /api/acs/v1/door/doControl
        /// 该接口支持门常开、门常闭、门开和门闭四种操作。门常开操作，门会一直处于开状态，不会自动关闭，执行门闭操作，门才会关上；
        /// 门常闭操作，门会一直处于关毕状态，普通卡刷卡门不会被打开，执行门开操作，门会打开；门开操作，执行门打开动作，超过门打开时间，门会自动关上；
        /// 门闭操作，执行关门动作，会立即把门关上。
        /// 调用该接口，首先要通过获取门禁点资源列表的接口，获取到门禁点唯一编号，然后根据门禁点唯一编号进行反控操作，该接口支持单个和多个门禁点操作，
        /// 如果所有门禁点反控操作成功，则返回成功，其他情况都返回失败，在失败的情况下，会按每个门禁点返回对应的错误。
        /// </summary>
        /// <param name="doorIndexCodes">必填 门禁点唯一标识，最大支持200个门禁点。查询门禁点列表v2接口获取返回参数doorIndexCode
        /// https://open.hikvision.com/docs/794bb3aa9864418780fae0efb9d8745b?curNodeId=794bb3aa9864418780fae0efb9d8745b#b40ec5e7
        /// </param>
        /// <param name="controlType">必填 0: 常开 1: 门闭 2: 门开 3: 常闭</param>
        /// <remarks>综合安防管理平台iSecure Center V1.0及以上版本</remarks>
        /// <returns><see cref="ResDoControl"/></returns>
        public async Task<ResParameter<IList<ResDoControl>>?> DoorDoControlAsync(IList<string> doorIndexCodes, int controlType) =>
          await SecureCenterApis.PostAsync<IList<ResDoControl>>("/api/acs/v1/door/doControl", 1.0, new { doorIndexCodes = doorIndexCodes, controlType = controlType });
        /// <summary>
        /// 查询门禁点事件v2 /api/acs/v2/door/events
        /// 功能描述：该接口可以查询发生在门禁点上的人员出入事件，支持多个维度来查询，支持按时间、人员、门禁点、事件类型四个维度来查询；
        /// 其中按事件类型来查询的方式，如果查询不到事件，存在两种情况，一种是该类型的事件没有发生过，
        /// 所以查询不到，还有一种情况，该类型的事件发生过，但是由于门禁管理组件对该事件类型订阅配置处于关闭状态，
        /// 所以不会存储该类型的事件，导致查询不到，对于这种情况，需要到门禁管理组件中，将该事件类型的订阅配置打开。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.4及以上版本</remarks>
        /// <param name="req">必填 参数</param>
        /// <returns><see cref="ResDoorEvents"/></returns>
        public async Task<ResParameter<ResPageData<ResDoorEvents>>?> DoorEventsAsync(ReqDoorEvents req) =>
          await SecureCenterApis.PostAsync<ResPageData<ResDoorEvents>>("/api/acs/v2/door/events ", 1.4, req);
        /// <summary>
        /// 获取门禁事件的图片 /api/acs/v1/event/pictures
        /// 获取门禁事件的图片,
        /// 配合门禁实时订阅事件附录D2.1 门禁事件使用,
        /// https://open.hikvision.com/docs/a342242ec21044b9a6989a559c9464be?curNodeId=a342242ec21044b9a6989a559c9464be
        /// 或配合查询门禁点事件v2接口使用
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.0及以上版本</remarks>
        /// <param name="svrIndexCode">必填 提供picUri处会提供此字段</param>
        /// <param name="picUri">必填 图片相对地址</param>
        /// <returns><see cref="ResParameter{T}"/></returns>
        public async Task<ResParameter<object>?> RegionsRootAsync(string svrIndexCode, string picUri) =>
          await SecureCenterApis.PostAsync<object>("/api/acs/v1/event/pictures", 1.0, new { svrIndexCode = svrIndexCode, picUri = picUri });
        #endregion

        #region 门禁资源接口
        /// <summary>
        /// 查询门禁设备列表v2 /api/resource/v2/acsDevice/search
        /// 根据条件查询目录下有权限的门禁设备列表。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.4及以上版本</remarks>
        /// <returns><see cref="ResAcsDevice"/></returns>
        public async Task<ResParameter<ResPageData<ResAcsDevice>>?> RegionsRootAsync(ReqDoorSearch req) =>
          await SecureCenterApis.PostAsync<ResPageData<ResAcsDevice>>("/api/resource/v1/regions/root", 1.4);
        /// <summary>
        /// 增量获取门禁设备数据 /api/resource/v1/acsDevice/timeRange
        /// 根据资源类型、时间段增量获取资源，包含已删除数据。开始日期与结束日期的时间差必须在1-48小时内。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.4及以上版本</remarks>
        /// <param name="page">必填，页码、页大小、开始时间、结束时间</param>
        /// <returns><see cref="ResAcsDevice"/></returns>
        public async Task<ResParameter<ResPageData<ResAcsDevice>>?> AcsDeviceTimeRangeAsync(ReqPageDate page) =>
          await SecureCenterApis.PostAsync<ResPageData<ResAcsDevice>>("/api/resource/v1/acsDevice/timeRange", 1.4, page);
        /// <summary>
        /// 查询门禁点列表v2 /api/resource/v2/door/search
        /// 根据条件查询目录下有权限的门禁点列表。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.4及以上版本</remarks>
        /// <param name="req">参数</param>
        /// <returns><see cref="ResDoor"/></returns>
        public async Task<ResParameter<ResPageData<ResDoor>>?> DoorSearchAsync(ReqDoorSearch req) =>
          await SecureCenterApis.PostAsync<ResPageData<ResDoor>>("/api/resource/v2/door/search", 1.4, req);
        /// <summary>
        /// 增量获取门禁点数据 /api/resource/v1/door/timeRange
        /// 根据资源类型、时间段增量获取资源，包含已删除数据。开始日期与结束日期的时间差必须在1-48小时内。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.4及以上版本</remarks>
        /// <param name="page">必填，页码、页大小</param>
        /// <returns><see cref="ResDoor"/></returns>
        public async Task<ResParameter<ResPageData<ResDoor>>?> DoorTimeRangeAsync(ReqPageDate page) =>
          await SecureCenterApis.PostAsync<ResPageData<ResDoor>>("/api/resource/v1/door/timeRange", 1.4, page);
        /// <summary>
        /// 查询门禁读卡器列表 /api/resource/v1/reader/search
        /// 查询目录下有权限的门禁读卡器列表。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.3及以上版本</remarks>
        /// <param name="name">非必填，名称，模糊搜索 若包含中文，最大长度指不超过按照指定编码的字节长度，即getBytes(“utf-8”).length 最大长度：32</param>
        /// <param name="regionIndexCodes">非必填，区域编号,可以为空;String[]，支持根据区域批量查询； 区域编号个数<=1000个； 单个长度<=64Byte</param>
        /// <param name="isSubRegion">非必填，是否包含下级区域，注： 1、参数containSubRegion和regionIndexCodes必须同时存在，且regionIndexCodes只能指定一个区域编码</param>
        /// <param name="page">非必填，</param>
        /// <param name="capabilitySet">非必填，设备能力集(含设备上的智能能力)，详见附录A.44 设备能力集
        /// https://open.hikvision.com/docs/0f6e8e1e41a14304aeecd287530b9c95?curNodeId=0f6e8e1e41a14304aeecd287530b9c95#e043207b
        /// </param>
        /// <param name="orderBy">非必填，排序字段,注意：排序字段必须是查询条件，否则返回参数错误</param>
        /// <param name="orderType">非必填，排序字段,注意：排序字段必须是查询条件，否则返回参数错误</param>
        /// <returns><see cref="ResReader"/></returns>
        public async Task<ResParameter<ResPageData<ResReader>>?> ReaderSearchAsync(string name = null, IList<string> regionIndexCodes = null, bool isSubRegion = true,
            ReqPage page = null, IList<string> capabilitySet = null, string orderBy = null, string orderType = null) =>
          await SecureCenterApis.PostAsync<ResPageData<ResReader>>("/api/resource/v1/reader/search", 1.3, new
          {
              name = name,
              regionIndexCodes = regionIndexCodes,
              pageNo = page?.pageNo ?? 1,
              pageSize = page?.pageSize ?? 10,
              capabilitySet = capabilitySet,
              orderBy = orderBy,
              orderType = orderType
          });
        /// <summary>
        /// 增量获取门禁读卡器数据 /api/resource/v1/reader/timeRange
        /// 根据资源类型、时间段增量获取资源，包含已删除数据。其中开始日期与结束日期的时间差必须在1-48小时内。
        /// 当返回字段对应的值为空时，该字段不返回。
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.4及以上版本</remarks>
        /// <param name="page">参数</param>
        /// <returns><see cref="ResReader"/></returns>
        public async Task<ResParameter<ResPageData<ResReader>>?> ReaderTimeTangeAsync(ReqPageDate page) =>
          await SecureCenterApis.PostAsync<ResPageData<ResReader>>("/api/resource/v1/reader/timeRange", 1.4, page);
        #endregion

        #region 门禁网管接口
        /// <summary>
        /// 获取门禁设备在线状态 /api/nms/v1/online/acs_device/get
        /// 根据条件获取门禁设备在线状态接口
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.3及以上版本</remarks>
        /// <param name="regionId">非必填，区域id , 分页获取区域列表接口可以获取</param>
        /// <param name="ip">非必填，设备ip，用户可以自己手动输入，也可以根据查询门禁点列表v2接口可以获取</param>
        /// <param name="indexCodes">非必填，读卡器列表，最大500，查询门禁读卡器列表接口可以获取接口可以获取</param>
        /// <param name="status">非必填，状态 1: 在线 0: 离线 -1: 未检测</param>
        /// <param name="page">非必填，页码，页大小</param>
        /// <param name="includeSubNode">非必填，是否包含下级，1包含，0不包含（若regionId为空，则该参数不起作用）</param>
        /// <returns><see cref="ResOnline"/></returns>
        public async Task<ResParameter<ResPageData<ResOnline>>?> GetAcsDeviceOnlineAsync(string regionId = null, string ip = null, IList<string> indexCodes = null, string status = null,
            ReqPage page = null, string includeSubNode = null) =>
          await SecureCenterApis.PostAsync<ResPageData<ResOnline>>("/api/nms/v1/online/acs_device/get", 1.3, new
          {
              regionId = regionId,
              ip = ip,
              indexCodes = indexCodes,
              status = status,
              pageNo = page?.pageNo ?? 1,
              pageSize = page?.pageSize ?? 10,
              includeSubNode = includeSubNode
          });
        /// <summary>
        /// 获取门禁读卡器在线状态 /api/nms/v1/online/reader/get
        /// 根据条件获取门禁卡器在线状态接口
        /// </summary>
        /// <remarks>综合安防管理平台iSecure Center V1.3及以上版本</remarks>
        /// <param name="regionId">非必填，区域id , 分页获取区域列表接口可以获取</param>
        /// <param name="indexCodes">非必填，读卡器列表，最大500，查询门禁读卡器列表接口可以获取接口可以获取</param>
        /// <param name="status">非必填，状态 1: 在线 0: 离线 -1: 未检测</param>
        /// <param name="page">非必填，页码，页大小</param>
        /// <param name="includeSubNode">非必填，是否包含下级，1包含，0不包含（若regionId为空，则该参数不起作用）</param>
        /// <returns><see cref="ResOnline"/></returns>
        public async Task<ResParameter<ResPageData<ResOnline>>?> GerReaderOnlineAsync(string regionId = null, IList<string> indexCodes = null, string status = null,
            ReqPage page = null, string includeSubNode = null) =>
          await SecureCenterApis.PostAsync<ResPageData<ResOnline>>("/api/nms/v1/online/reader/get", 1.3, new
          {
              regionId = regionId,
              indexCodes = indexCodes,
              status = status,
              pageNo = page?.pageNo ?? 1,
              pageSize = page?.pageSize ?? 10,
              includeSubNode = includeSubNode
          });
        #endregion
    }
}
